
package com.jf.cloud.service.sysmanager.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.jf.cloud.service.sysmanager.entity.PubgMatch;
import com.jf.cloud.service.sysmanager.entity.PubgMatchSettlement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.jf.cloud.service.sysmanager.common.base.BaseService;
import com.jf.cloud.service.sysmanager.common.base.GenericsUtils;
import com.jf.cloud.service.sysmanager.common.db.BaseDao;
import com.jf.cloud.service.sysmanager.common.db.Condition;
import com.jf.cloud.service.sysmanager.common.db.jdbc.RowMapperFactory;
import com.jf.cloud.service.sysmanager.common.util.NumberUtil;
import com.jf.cloud.service.sysmanager.common.util.ObjectUtil;
import com.jf.cloud.service.sysmanager.dao.IPubgUserMatchService;
import com.jf.cloud.service.sysmanager.entity.PubgUserMatch;


/**
 * 员工服务实现
 * 
 * @author 绝峰代码机1.0 创建时间：2018-03-31
 */
@Service("pubgUserMatchService")
public class PubgUserMatchServiceImpl extends BaseService<PubgUserMatch, Long> implements IPubgUserMatchService {

	/**
	 * 日志
	 */
	private static Log log = LogFactory.getLog(PubgUserMatchServiceImpl.class);

	/**
	 * JPA公共DAO
	 */
	@Resource
	private BaseDao baseDao;

	private RowMapper<PubgUserMatch> rowMapper = new BeanPropertyRowMapper<PubgUserMatch>(GenericsUtils.getSuperClassGenricType(this.getClass()));

	/**
	 * 根据主键查询员工
	 * 
	 * @author 绝峰代码机1.0 创建时间：2018-03-31
	 */
	public PubgUserMatch findPubgUserMatch(Long rowId) throws Exception {
		try {
			return this.baseDao.findObject("", rowMapper, rowId);
		} catch (Exception e) {
			throw new Exception("根据主键查询员工出错！", e);
		}
	}

	/**
	 * 根据查询条件获取员工列表
	 * 
	 * @author 绝峰代码机1.0 创建时间：2018-03-31
	 */
	public List<PubgUserMatch> findPubgUserMatchList(Condition qc) throws Exception {
		try {
			return this.baseDao.findList("", rowMapper);
		} catch (Exception e) {
			throw new Exception("根据查询条件获取员工列表出错！", e);
		}
	}

	/**
	 * 新增/修改员工
	 * 
	 * @author 绝峰代码机1.0 创建时间：2018-03-31
	 */
	@Transactional
	public PubgUserMatch saveOrUpdatePubgUserMatch(PubgUserMatch pubgUserMatch) throws Exception {
		try {
			return this.baseDao.saveAll(pubgUserMatch);
		} catch (Exception e) {
			throw new Exception("新增/修改员工出错！", e);
		}
	}

	/**
	 * 确认名次
	 * @param pubgUserMatch
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) //任何异常 都需要回滚
	public boolean saveMatchTResult(PubgUserMatch pubgUserMatch, PubgMatchSettlement pubgMatchSettlement, PubgMatch pubgMatch) throws Exception {
		boolean flag = false;
		try{
			String sql = " UPDATE pubg_user_match SET RESULT_SUBMIT_TIME=?,MATCH_RESULT=? WHERE ROW_ID=? ";
			this.baseDao.update(sql, pubgUserMatch.getResultSubmitTime(), pubgUserMatch.getMatchResult(), pubgUserMatch.getRowId());
			this.baseDao.saveAll(pubgMatchSettlement);
			
			// 计算队员、战队、俱乐部所得金额
			computeMatchBonus(pubgMatchSettlement, pubgMatch);
			
			flag = true;
		}catch (Exception e){
			log.info("确认修改名次失败");
		}
		return flag;
	}


	/**
	 * 查询俱乐部战队信息
	 * @return
	 */
	public Map<String,Object> getUserInfo(String rowId){
		Map<String, Object> rs = new HashMap<>();
		String sql = " SELECT b.CLUB_ID clubId, b.CLUB_NAME clubName, b.ROW_ID, b.TEAM_NAME FROM pubg_match a LEFT JOIN pubg_team b ON a.MATCH_TEAM_ID IN  (b.ROW_ID+',') "
				+" WHERE a.ROW_ID = ? ";
		try{
			rs = baseDao.findMap(sql, rowId);
		}catch (Exception e){
			log.info("查询俱乐部战队信息失败");
		}
		return rs;
	}


	/**
	 * 修改名次
	 * @param pubgUserMatch
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) //任何异常 都需要回滚
	public boolean updateMatchTResult(PubgUserMatch pubgUserMatch, PubgMatchSettlement pubgMatchSettlement, PubgMatch pubgMatch) throws Exception {
		boolean flag = false;
		try{
			String sql = " UPDATE pubg_user_match SET RESULT_SUBMIT_TIME=?,MATCH_RESULT=? WHERE ROW_ID=? ";
			this.baseDao.update(sql, pubgUserMatch.getResultSubmitTime(), pubgUserMatch.getMatchResult(), pubgUserMatch.getRowId());
			String updateSql = " UPDATE pubg_match_settlement SET MATCH_RESULT=?,RESULT_SUBMIT_TIME=?,OBTAIN_RANK=? WHERE ROW_ID=? ";
			this.baseDao.update(updateSql, pubgMatchSettlement.getMatchResult(), pubgMatchSettlement.getResultSubmitTime(), pubgMatchSettlement.getObtainRank(), pubgMatchSettlement.getRowId());

			// 计算队员、战队、俱乐部所得金额
			computeMatchBonus(pubgMatchSettlement, pubgMatch);
			
			flag = true;
		}catch (Exception e){
			throw new RuntimeException("修改名次失败", e);
		}
		return flag;
	}

    
    /**
     * 计算队员、战队、俱乐部所得金额
     * 
     * @author 朱建文 创建时间：2018年4月8日 下午7:54:06
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) //任何异常 都需要回滚
    private void computeMatchBonus(PubgMatchSettlement matchSettlement, PubgMatch pubgMatch) throws Exception {
    	StringBuffer sb = new StringBuffer();
    	try {
    		
    		// 删除赛事奖励
    		sb.append(" DELETE FROM pubg_match_settlement WHERE MATCH_ID = ? AND USER_ID IS NULL ");
    		this.baseDao.safeUpdate(sb.toString(), 0, pubgMatch.getRowId());
    		
			// 查询队员名次及获取比例（按名次分组）
    		sb = new StringBuffer();
			sb.append(" SELECT ");
			sb.append("   b.USER_ID userId, b.USER_ACCOUNT userAccount, b.TEAM_ID teamId, b.TEAM_NAME teamName, b.OBTAIN_RANK obtainBank, ");
			sb.append("   b.CLUB_ID clubId, b.CLUB_NAME clubName, a.AWARD_VALUE awardValue, b.INVITE_FROM inviteFrom ");
			sb.append(" FROM ");
			sb.append("   pubg_match_reward a LEFT JOIN pubg_match_settlement b ");
			sb.append("   ON a.MATCH_ID = b.MATCH_ID AND a.RANKING = b.OBTAIN_RANK ");
			sb.append(" WHERE ");
			sb.append("   b.MATCH_ID = ? ");
			List<Map<String, Object>> dataList = this.baseDao.findMapList(sb.toString(), pubgMatch.getRowId());
			
			// 查询每个名次的获奖人数SQL
			String selectEveryRank = "SELECT MATCH_ID, CLUB_ID, CLUB_NAME, TEAM_ID, TEAM_NAME, ";
			selectEveryRank += " USER_ID, USER_ACCOUNT, USER_ACCOUNT, OBTAIN_RANK ";
			selectEveryRank += " FROM pubg_match_settlement WHERE MATCH_ID = ? AND OBTAIN_RANK = ? ";
			List<PubgMatchSettlement> matchSettlementList = null; // 查询结果
			
			double awardValue = 0.0; // 奖励比值
			double rankAwardSum = 0.0, rankAward = 0.0; // 队员获取的奖励
			double memberAwardSum = 0.0; // 队员奖励总计
			PubgMatchSettlement pubgMatchSettlement = null;
			for (Map<String, Object> map : dataList) {
				awardValue = ObjectUtil.convert(map.get("awardValue") + "", 0.0);
				
				// 计算每个名次的获奖金额
				rankAwardSum = pubgMatch.getApplySumTemp() * awardValue;
				
				// 查询每个名次的获奖人数
				matchSettlementList = this.baseDao.findList(selectEveryRank, 
						RowMapperFactory.newInstance(PubgMatchSettlement.class), pubgMatch.getRowId(), map.get("obtainBank"));
				for (PubgMatchSettlement winMember : matchSettlementList) {
					
					// 目前是每个获奖者 平分 名次奖金   （保留2位小数，其余的直接抹掉，高老师定的）
					rankAward = NumberUtil.getPrice(rankAwardSum / matchSettlementList.size());
					if ((rankAward + "").indexOf(".") > 0 && (rankAward + "").substring((rankAward + "").indexOf(".") + 1).length() > 2) {
						rankAward = ObjectUtil.convertDouble((rankAward + "").substring(0, (rankAward + "").indexOf(".") + 3));
					}
					
					// 更新 赛事资金表 奖励所得
					sb = new StringBuffer();
					sb.append(" UPDATE ");
					sb.append("   pubg_match_settlement ");
					sb.append(" SET ");
					sb.append("   OBTAIN_AWARD = ? ");
					sb.append(" WHERE ");
					sb.append("   MATCH_ID = ? AND TEAM_ID = ? AND USER_ID = ? AND OBTAIN_RANK = ?");
					this.baseDao.safeUpdate(sb.toString(), 1, rankAward, pubgMatch.getRowId(), winMember.getTeamId(),
							winMember.getUserId(), winMember.getObtainRank());
				}
				
				// 计算所有队员的奖励总和
				memberAwardSum += rankAward;
			}
			
			// 计算总利润		利润 = 总费用 - 用户奖励
			double profitSum = pubgMatch.getApplySumTemp() - memberAwardSum;
			if ((profitSum + "").indexOf(".") > 0 && (profitSum + "").substring((profitSum + "").indexOf(".") + 1).length() > 2) {
				profitSum = ObjectUtil.convertDouble((profitSum + "").substring(0, (profitSum + "").indexOf(".") + 3));
			}
			
			// 查询每个战队的贡献人数
			sb = new StringBuffer();
			sb.append(" SELECT ");
			sb.append("   MATCH_ID matchId, CLUB_ID clubId, CLUB_NAME clubName, TEAM_ID teamId, TEAM_NAME teamName, COUNT(0) memberNum ");
			sb.append(" FROM ");
			sb.append("   pubg_user_match ");
			sb.append(" WHERE ");
			sb.append("   MATCH_ID = ? AND CLUB_ID = ? AND USER_STATE = 20 AND INVITE_FROM = 1 ");
			sb.append(" GROUP BY ");
			sb.append("   TEAM_ID ");
			dataList = this.baseDao.findMapList(sb.toString(), pubgMatch.getRowId(), pubgMatch.getClubId());
			
			// 查询战队的分成比例SQL
			sb = new StringBuffer();
			sb.append(" SELECT SETTLEMENT_RATIO FROM pubg_team WHERE ROW_ID = ?");
			
			// 计算战队所得	战队提成 = 战队贡献比 * 提成比例 * 总利润
			Integer memberNum = 0; // 战队的人数
			double teamRatio = 0.0, teamProfit = 0.0;
			double teamProfitSum = 0.0; // 战队提成之和
			for (Map<String, Object> map : dataList) {
				
				// 查询战队的分成比例
				teamRatio = this.baseDao.find(sb.toString(), Double.class, map.get("teamId"));
				
				memberNum = ObjectUtil.convert(map.get("memberNum"), 0);
				teamProfit = (memberNum.doubleValue() / pubgMatch.getMatchPeopleNum().doubleValue()) * teamRatio * profitSum;
				
				// 插入分成记录
				pubgMatchSettlement = new PubgMatchSettlement();
				pubgMatchSettlement.setMatchId(pubgMatch.getRowId());
				pubgMatchSettlement.setMatchName(pubgMatch.getMatchName());
				pubgMatchSettlement.setMatchType(pubgMatch.getMatchTypeId());
				pubgMatchSettlement.setMatchTypeName(pubgMatch.getMatchTeamName());
				pubgMatchSettlement.setApplyFee(pubgMatch.getApplyFee());
				pubgMatchSettlement.setClubId(ObjectUtil.convertLong(map.get("clubId")));
				pubgMatchSettlement.setClubName(ObjectUtil.convert(map.get("clubName")));
				pubgMatchSettlement.setTeamId(ObjectUtil.convertLong(map.get("teamId")));
				pubgMatchSettlement.setTeamName(ObjectUtil.convert(map.get("teamName")));
				pubgMatchSettlement.setResultSubmitId(matchSettlement.getResultSubmitId());
				pubgMatchSettlement.setResultSubmitAccount(matchSettlement.getResultSubmitAccount());
				pubgMatchSettlement.setResultSubmitTime(matchSettlement.getResultSubmitTime());
				pubgMatchSettlement.setObtainAward(teamProfit);
				this.baseDao.saveAll(pubgMatchSettlement);
				teamProfitSum += teamProfit;
			}
			
			// 计算俱乐部所得     俱乐部收入 = 利润 - 战队提成之和
			double clubProfit = profitSum - teamProfitSum;
			if ((clubProfit + "").indexOf(".") > 0 && (clubProfit + "").substring((clubProfit + "").indexOf(".") + 1).length() > 2) {
				clubProfit = ObjectUtil.convertDouble((clubProfit + "").substring(0, (clubProfit + "").indexOf(".") + 3));
			}
			
			// 插入分成记录
			pubgMatchSettlement = new PubgMatchSettlement();
			pubgMatchSettlement.setMatchId(pubgMatch.getRowId());
			pubgMatchSettlement.setMatchName(pubgMatch.getMatchName());
			pubgMatchSettlement.setMatchType(pubgMatch.getMatchTypeId());
			pubgMatchSettlement.setMatchTypeName(pubgMatch.getMatchTeamName());
			pubgMatchSettlement.setApplyFee(pubgMatch.getApplyFee());
			pubgMatchSettlement.setClubId(pubgMatch.getClubId());
			pubgMatchSettlement.setClubName(pubgMatch.getClubName());
			pubgMatchSettlement.setResultSubmitId(matchSettlement.getResultSubmitId());
			pubgMatchSettlement.setResultSubmitAccount(matchSettlement.getResultSubmitAccount());
			pubgMatchSettlement.setResultSubmitTime(matchSettlement.getResultSubmitTime());
			pubgMatchSettlement.setObtainAward(clubProfit);
			this.baseDao.saveAll(pubgMatchSettlement);
		} catch (Exception e) {
			throw new RuntimeException("计算队员、战队、俱乐部所得金额出错！", e);
		}
    }

}
